<?
/*

    This file is part of Blue Violin.

    Blue Violin is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Blue Violin is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero Public License for more details.

    You should have received a copy of the GNU Affero Public License
    along with Blue Violin.  If not, see <http://www.gnu.org/licenses/>.

    Blue Violin  Copyright (C) 2008  Blue Violin, Inc. & Josh Watts <josh.watts@blueviolin.org>
	For more information, visit http://www.blueviolin.org/

    This program comes with ABSOLUTELY NO WARRANTY.

*/

require_once("classes_general.inc");
require_once("Utility.php");
require_once("Database.php");



class Email
{
	private $m_connEmail;
	private $m_aTypes;
	private $m_objDatabase;
	
// 	public function __construct()
// 	{
// 		$strUser = preg_replace("/\'/", "", $_COOKIE["user"]);
// 		$strPassword = $_COOKIE["password"];
// 		$strMailbox = "{" . EMAILHOST . ":" . IMAPPORT . "/imap}";
// // 		$this->m_connEmail = imap_open("{127.0.0.1:143/imap}", "josh", "nanoenvy", OP_SILENT);
// // 		$this->m_connEmail = imap_open($strMailbox, $strUser, $strPassword, OP_SILENT);
// 		$this->m_connEmail = imap_open($strMailbox, $strUser, $strPassword);
// 		$this->m_aTypes = array(0 => "text",
// 									 "multipart",
// 									 "message",
// 									 "application",
// 									 "audio",
// 									 "image",
// 									 "video",
// 									 "other");
// 		$this->__construct("INBOX");
		
// 	}

	public function __construct($strMailbox = "INBOX")
	{
		$this->m_objDatabase = new Database;
		$strUser = preg_replace("/\'/", "", $_COOKIE["user"]);
		$strPassword = $_COOKIE["password"];
		$strMailbox = "{" . EMAILHOST . ":" . IMAPPORT . "/imap}" . $strMailbox;
// 		$this->m_connEmail = imap_open("{127.0.0.1:143/imap}", "josh", "nanoenvy", OP_SILENT);
// 		$this->m_connEmail = imap_open($strMailbox, $strUser, $strPassword, OP_SILENT);
		$this->m_connEmail = imap_open($strMailbox, $strUser, $strPassword);
		$this->m_aTypes = array(0 => "text",
									 "multipart",
									 "message",
									 "application",
									 "audio",
									 "image",
									 "video",
									 "other");
	}

	public function __destruct()
	{
		imap_close($this->m_connEmail);
	}

	public function GetFolderList()
	{
		// $aList = imap_list($this->m_connEmail, "{" . EMAILHOST . "/imap/notls}", "*");
		$aList = imap_list($this->m_connEmail, "{" . EMAILHOST . ":" . IMAPPORT . "/imap}", "*");
		foreach ($aList as &$strFolderName)
		{
			$strFolderName = preg_replace("/\{.+\}/", "", $strFolderName);
		}
		return $aList;
	}

	public function GetEmailHeaders()
	{
		$aHeaders = array();
		$nMessages = imap_num_msg($this->m_connEmail);
		for ($i = 1;
			 $i <= $nMessages ;
			 $i++)
		{
			$aHeaders[$i] = imap_headerinfo($this->m_connEmail, $i);
		}
		return $aHeaders;
	}

	public function GetEmailHeader($nMessageID)
	{
		// we have to check to see the email, specifified by $nMessageID
		// actually exists; otherwise, imap_headerinfo displays an error
		$nMessages = imap_num_msg($this->m_connEmail);
		if ($nMessages < $nMessageID)
		{
			return false;
		}
		else
		{
			$objHeader = imap_headerinfo($this->m_connEmail, $nMessageID);
			return $objHeader;
		}
	}

	public function GetMessageBody($nMessageID)
	{
		$aBody = array();
		$objStructure = imap_fetchstructure($this->m_connEmail, $nMessageID);
		if (false == isset($objStructure->parts))
		{
			// email doesn't contain parts (i.e. no attachments)
			// so just get the plain text email message
			$strBody = imap_body($this->m_connEmail, $nMessageID);
			$aBody["plain"] = $strBody;
			return $aBody;
		}
		$nParts = count($objStructure->parts);
		for ($i = 0;
			 $i < $nParts;
			 $i++)
		{
			$strType = $objStructure->parts[$i]->type;
			$nEncoding = $objStructure->parts[$i]->encoding;
			$strSubtype = strtolower($objStructure->parts[$i]->subtype);
			$strBody = imap_fetchbody($this->m_connEmail, $nMessageID, $i+1);
			$strBody = $this->Decode($strBody, $nEncoding);
			$aBody[$strSubtype] = $strBody;
		}
		return $aBody;
	}

	public function ScanAttachments($nMessageID)
	{
		$aAttachments = array();
		$nCount = 0;
		$objStructure = imap_fetchstructure($this->m_connEmail, $nMessageID);
		// see if the email contains any attachments
		if (false == isset($objStructure->parts))
		{
			return false;
		}
		$nParts = count($objStructure->parts);
		for ($i = 0;
			 $i < $nParts;
			 $i++)
		{
			$strType = $objStructure->parts[$i]->type;
			$nEncoding = $objStructure->parts[$i]->encoding;
			// echo count($this->m_aEncodings) . " / "  . $nEncoding . " / mime_type = " . $this->m_aEncodings[$nEncoding] . "<br/>";
			$strSubtype = strtolower($objStructure->parts[$i]->subtype);
			if ("plain" != $strSubtype &&
				"html" != $strSubtype)
			{
				if (isset($objStructure->parts))
				{
					// get description
					if (isset($objStructure->parts[$i]->description))
					{
						$strDesc = $objStructure->parts[$i]->description;
					}
					else
					{
						$strDesc = "unknown";
					}
					// get the filename of the attachment, if it exists
					if (true == $objStructure->parts[$i]->ifdparameters)
					{
						if ("filename" == $objStructure->parts[$i]->dparameters[0]->attribute)
						{
							$strDesc = $objStructure->parts[$i]->dparameters[0]->value;
						}
					}
					//
					// ignore for now
					// handles attachments that contain attachments
					//
					// start
// 					if(isset($struct->parts[1]->parts) &&
// 					   count($struct->parts[$i]->parts) > 0)
// 					{
// 						$ntid = $tid;
// 						array_push($ntid,$i+1);
// 						scanAttachments($emailConn, $struct->parts[$i],$id,$ntid);
// 					}					
					// end
					//
					// imap_fetchbody is 1-based
					//
					$mAttachment = imap_fetchbody($this->m_connEmail, $nMessageID, $i+1);
					$mAttachment = $this->Decode($mAttachment, $nEncoding);
					$aAttachments[$nCount]["desc"] = $strDesc;
					$aAttachments[$nCount]["mime_type"] = $this->m_aTypes[$strType];
					$aAttachments[$nCount]["type"] = $strType;
					$aAttachments[$nCount]["subtype"] = $strSubtype;
					$aAttachments[$nCount]["size"] = strlen($mAttachment);
					$aAttachments[$nCount]["partid"] = $i;
					$nCount++;
				}
			}  
		}
		return $aAttachments;
	}

	private function Decode($mContent, $nEncoding)
	{
		$mRetVal = "";
		switch ($nEncoding)
		{
			case 3:
				// base64
				$mRetVal = base64_decode($mContent);
				break;
			case 4:
				// quoted-printable
				$mRetVal = imap_qprint($mContent);
				break;
			default:
				$mRetVal = $mContent;
				break;
		}
		return $mRetVal;
	}

	private function FindAppropriateBody($struct, $subtype, $id="")
	{
		// jw - variable names need to be "nice-ified"
		if(0 == $struct->type &&
		   strtolower($struct->subtype) == strtolower($subtype))
		{
			return array($id, $struct);
		}
		// jw
		// when we get into recrusion, sometimes $struct->parts doesn't exist
		//
		if (isset($struct->parts))
		{
			// echo count($struct->parts);
			$cnt = count($struct->parts);
			if(0 == $cnt)
			{
				return FALSE;
			}
			for($i = 0;
				$i < $cnt;
				$i++)
			{
				$rid = $this->FindAppropriateBody($struct->parts[$i], $subtype, "$id.".($i+1));
				if($rid != FALSE)
				{
					return $rid;
				}
			}
		}
		return FALSE;
	}

	public function GetAttachment($nMessageID, $nPartID)
	{
		$aAttachment = array();
		$objStructure = imap_fetchstructure($this->m_connEmail, $nMessageID);
		$objPart = $objStructure->parts[$nPartID];
		$mBody = imap_fetchbody($this->m_connEmail, $nMessageID, $nPartID+1);
		$mBody = $this->Decode($mBody, $objPart->encoding);
		$nMedia = $objPart->type;
		$aAttachment["type"] = $this->m_aTypes[$objPart->type];
		$aAttachment["subtype"] = strtolower($objPart->subtype);
		if (0 == $nMedia &&
			"html" == strtolower($objPart->subtype))
		{
			$aAttachment["content"] = $mBody;
		}
		elseif (1 == $nMedia ||
				(3 <= $nMedia &&
				 7 >= $nMedia))
		{
// 			$aAttachment["type"] = $objPart->type . "/" . $objPart->subtype;
			$aAttachment["filename"] = "unknown." . $objPart->subtype;
			if (true == $objPart->ifdparameters)
			{
				if ("filename" == $objPart->dparameters[0]->attribute)
				{
					$aAttachment["filename"] = $objPart->dparameters[0]->value;
				}
			}
			$aAttachment["size"] = strlen($mBody);
			$aAttachment["content"] = $mBody;
		}
		return $aAttachment;
	}

	public function CreateFolder($strFolderName)
	{
		$strFolderName = imap_utf7_encode($strFolderName);
		$bRetVal = imap_createmailbox($this->m_connEmail, "{" . EMAILHOST . ":" . IMAPPORT . "/imap}" . $strFolderName);
		return $strFolderName;
	}

	public function DeleteEmail($nMessageID)
	{
		$bRetVal = imap_delete($this->m_connEmail, $nMessageID);
		// imap_expunge($this->m_connEmail);
		return;
	}

	public function MoveEmails($strEmailList, $strMailbox)
	{
		$bRetVal = imap_mail_move($this->m_connEmail, $strEmailList, $strMailbox);
		imap_expunge($this->m_connEmail);
		return;
	}

	public function Flush()
	{
		imap_expunge($this->m_connEmail);
		return;
	}
	

	public function CreateHTMLPage($mPageID, $strPageName, $strHTML, $nCoachID, $strSubject, $strFileAttName, $strData, $strFileAttType)
	{
		try
		{
			$strSQL = "insert into html_pages (page_id, page_name, html_code, date_created, default_page,opened,coach_id,subject,att_name,att_base64,att_type) " .
				"values " .
				"('" . $mPageID . "', '" . $this->m_objDatabase->EscapeString($strPageName) . "', " .
				"'" . $this->m_objDatabase->EscapeString($strHTML) . "', NOW(), 'yes', '', '" . $nCoachID . "', " .
				"'" . $this->m_objDatabase->EscapeString($strSubject) . "', '" . $strFileAttName .
				"', '" . $this->m_objDatabase->EscapeString($strData) . "', '" . $this->m_objDatabase->EscapeString($strFileAttType) . "')";
			$this->m_objDatabase->ExecuteSQL($strSQL);
			return;
			
		}
		catch (Exception $e) {
			$objUtil = new Utility();
			$objUtil->HandleException($e);
		}
	}

	public function GetHTMLPage($strPageID)
	{
		try
		{
			$strSQL = "select * " .
				"from html_pages " .
				"where page_id = '" . $strPageID . "'";
			$nRows = $this->m_objDatabase->ExecuteSQL($strSQL);
			$aRow = $this->m_objDatabase->NextRow();
			return $aRow;
		}
		catch (Exception $e) {
			$objUtil = new Utility();
			$objUtil->HandleException($e);
		}
			
	}

	public function InsertHistory($nPageID, $nUserID, $strStatus)
	{
		try
		{
			$strSQL = "insert into email_history (stat_id, page_id, prospect_id, status) values " .
				"('', '" . $nPageID . "', '" . $nUserID . "', '" . $strStatus . "')";
			$this->m_objDatabase->ExecuteSQL($strSQL);
			return;
		}
		catch (Exception $e) {
			$objUtil = new Utility();
			$objUtil->HandleException($e);
		}
	}

	public function GetAddressParts($strEmailAddress)
	{
		$aAddress = explode(" ", $strEmailAddress);
		switch (count($aAddress))
		{
			case 0:
				$aAddress[0] = "";
				$aAddress[1] = "";
				$aAddress[2] = "";
				break;
			case 1:
				if (false == strpos($aAddress[0], "@"))
				{
					$aAddress[2] = $aAddress[0];
					$aAddress[0] = "";
					$aAddress[1] = "";
				}
				else
				{
					$aAddress[1] = "";
					$aAddress[2] = "";
				}
				break;
			case 2:
				$aAddress[2] = $aAddress[1];
				$aAddress[1] = "";
				break;
		}
		$aAddress["f_name"] = $aAddress[0];
		$aAddress["l_name"] = $aAddress[1];
		$aAddress["email"] = $aAddress[2];
		return $aAddress;
	}

	public function Send($strEmail, $strSubject, $strMessage, $strHeaders)
	{
		imap_mail($strEmail, $strSubject, $strMessage, $strHeaders);
	}

}

?>